/*
 *  Copyright (C) 2011 Jaime Pavlich-Mariscal
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package cl.ucn.disc.biblio.refcluster.reference;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Properties;

import javax.xml.bind.PropertyException;

import org.apache.log4j.Logger;

import cl.ucn.disc.biblio.refcluster.control.ReferenceClustererController;

/** Manages the settings of the system, which are stored at {@code $HOME/.refclusterer/refclusterer.properties}
 * @author Jaime Pavlich-Mariscal
 *
 */
public class Configuration {
	public static final String BIBLIO_DB_DESTINATION_FOLDER = "biblio-db.destination-folder";
	public static final String AUTHOR_CLUSTER_FILENAME = "authors.cluster-filename";
	public static final String AUTHORS_DISAMBIGUATE = "authors.disambiguate";
	public static final String REFERENCE_CLUSTER_FILENAME = "references.cluster-filename";
	public static final String BIBLIO_DB_SOURCE_FOLDER = "biblio-db.source-folder";

	
	private static final String CONFIG_DIR = ".refcluster";
	private static final String CONFIG_FILE = "refcluster.properties";
    private static final Logger LOGGER = Logger.getLogger(ReferenceClustererController.class.getName());
	private File propertiesFile;
	private Properties properties;
	
	
	
	
	public Configuration() throws PropertyException {
		initProperties();
	}
	
	public String getProperty(String key) {
		return properties.getProperty(key);
	}
	
	public Object setProperty(String key, String value) {
		return properties.setProperty(key, value);
	}
	


	public void save() throws PropertyException {
		try {
			FileOutputStream out = new FileOutputStream(propertiesFile.getAbsolutePath());
			LOGGER.info("Writing properties file: " + propertiesFile.getAbsolutePath());
			properties.store(out, "RefClusterer properties file");
			out.close();
		} catch (Exception e) {
			throw new PropertyException(e);
		}
	}
	
	/** Obtains the properties file (and creates it with default values if it does not exist) 
	 * @throws PropertyException 
	 * 
	 */
	private Properties initProperties() throws PropertyException {
		try {
			File dir = getConfigDir();
			propertiesFile = new File(dir.getAbsolutePath() + File.separator + CONFIG_FILE);
			properties = new Properties();
			if (propertiesFile.exists()) {
				FileInputStream in = new FileInputStream(propertiesFile);
				properties.load(in);
				in.close();
			} else {
				// Creates property file with default values
				properties.setProperty(BIBLIO_DB_SOURCE_FOLDER, "/RefClusterer/DB");
				properties.setProperty(REFERENCE_CLUSTER_FILENAME, "/RefClusterer/reference_clusters.txt");
				properties.setProperty(AUTHORS_DISAMBIGUATE, "true");
				properties.setProperty(AUTHOR_CLUSTER_FILENAME, "/RefClusterer/author_clusters.txt");
				properties.setProperty(BIBLIO_DB_DESTINATION_FOLDER, "/RefClusterer/NewDB");
				save();
			}
			
			return properties;
		} catch (Exception e) {
			throw new PropertyException(e);
		}
	}

	
	/** Obtains the config Dir (and creates it if it does not exist) 
	 * @return
	 * Credits: http://stackoverflow.com/questions/193474/how-to-create-an-ini-file-to-store-some-settings-in-java
	 * @throws PropertyException 
	 */
	private File getConfigDir() throws PropertyException {
	    String userHome = System.getProperty("user.home");
	    if(userHome == null) {
	        throw new PropertyException("user.home==null");
	    }
	    File home = new File(userHome);
	    File settingsDirectory = new File(home, CONFIG_DIR);
	    if(!settingsDirectory.exists()) {
	        if(!settingsDirectory.mkdir()) {
	            throw new PropertyException("Cannot create: " + settingsDirectory.toString());
	        }
	    }
	    return settingsDirectory;
	}
}
